//-----------------------------------------------------------------------
// <copyright file="QueryProvider.cs" company="Rhys Parry">
//    Copyright Rhys Parry 2009
//    This file is released under the Apache 2.0 License
//    This class is based on Matt Warren's class described in the blog
//    post:
//    http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx
// </copyright>
//-----------------------------------------------------------------------
namespace Smarts.Core.Linq
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;

    public abstract class QueryProvider : IQueryProvider
    {
        IQueryable<T> IQueryProvider.CreateQuery<T>(Expression expression)
        {
            return new Query<T>(this, expression);
        }

        IQueryable IQueryProvider.CreateQuery(Expression expression)
        {
            var elementType = TypeSystem.GetElementType(expression.Type);
            try
            {
                return (IQueryable)Activator.CreateInstance(typeof(Query<>).MakeGenericType(elementType), new object[] { this, expression });
            }

            catch (TargetInvocationException invocationException)
            {
                throw invocationException.InnerException;
            }
        }

        T IQueryProvider.Execute<T>(Expression expression)
        {
            return (T)Execute(expression);
        }

        object IQueryProvider.Execute(Expression expression)
        {
            return Execute(expression);
        }

        public abstract string GetQueryText(Expression expression);

        public abstract object Execute(Expression expression);
    }
}